package com.kesh.ltank.elements;

import android.graphics.Point;

import com.kesh.ltank.game.GlobalVars;
import com.kesh.ltank.game.GlobalVars.Difficulty;
import com.kesh.ltank.game.GlobalVars.PlayObjects;
import com.kesh.ltank.game.Utils;

public class Level {

	private final byte[] lvlData = GlobalVars.lvlData;

	private final Point lvlFieldLen = GlobalVars.lvlFieldLen;
	private final int lvlFieldTotalLen = lvlFieldLen.x * lvlFieldLen.y;
	private final int lvlNameLen = 31;
	private final int lvlHintLen = 256;
	private final int lvlAuthorLen = 31;
	private final int lvlDcltyLen = 2;
	private final int lvlLen = lvlFieldTotalLen + lvlNameLen + lvlHintLen + lvlAuthorLen + lvlDcltyLen;

	private int lvlNum;
	private PlayObjects[][] lvlBaseField;
	private PlayObjects[][] lvlPlayField;
	private String lvlName;
	private String lvlHint;
	private String lvlAuthor;
	private Difficulty lvlDclty;
	
	private Point tankOrigPos;
	
	public Level() {
		lvlNum = 1;
		lvlBaseField = new PlayObjects[lvlFieldLen.x][lvlFieldLen.y];
		lvlPlayField = new PlayObjects[lvlFieldLen.x][lvlFieldLen.y];
		lvlDclty = Difficulty.Easy;
	}

	public void loadLevel(int inLvlNum) {

		lvlNum = inLvlNum;

		char[] tmpLvlName = new char[lvlNameLen];
		char[] tmpLvlAuthor = new char[lvlAuthorLen];
		char[] tmpLvlHint = new char[lvlHintLen];
		int[] tmpLvlDclty = new int[lvlDcltyLen];

		int lvlStrt, lvlPlayFieldStrt, lvlPlayFieldEnd, lvlNameStrt, lvlNameEnd, lvlHintStrt, lvlHintEnd, lvlAuthorStrt, lvlAuthorEnd, lvlDcltyStrt, lvlDcltyEnd, lvlEnd;

		try {

			lvlStrt = lvlPlayFieldStrt = (lvlNum - 1) * lvlLen;
			lvlPlayFieldEnd = lvlNameStrt = lvlPlayFieldStrt + lvlFieldTotalLen;
			lvlNameEnd = lvlHintStrt = lvlNameStrt + lvlNameLen;
			lvlHintEnd = lvlAuthorStrt = lvlHintStrt + lvlHintLen;
			lvlAuthorEnd = lvlDcltyStrt = lvlAuthorStrt + lvlAuthorLen;
			lvlDcltyEnd = lvlEnd = lvlDcltyStrt + lvlDcltyLen;

			int r = 0, c = 0;

			for (int i = lvlStrt; i < lvlEnd; i++) {
				if (i < lvlPlayFieldEnd) {
					if (c == 16) {
						r++;
						c = 0;
					}
					
					PlayObjects po = Utils.getPlayObject(lvlData[i]);
					switch (po) {
						case ATank_D:case ATank_L:case ATank_R:case ATank_U:case MBlock:case MMirror_D:case MMirror_L:case MMirror_R:case MMirror_U:case Flag:
						case RMirror_D:case RMirror_L: case RMirror_R: case RMirror_U:
							lvlBaseField[r][c] = PlayObjects.Ground;
							lvlPlayField[r][c] = po;
							break;
						case LTank_U:
							lvlBaseField[r][c] = PlayObjects.Ground;
							lvlPlayField[r][c] = po;
							tankOrigPos = new Point(r, c);
							break;
						default:
							lvlBaseField[r][c] = po;
							lvlPlayField[r][c] = po;
							break;
					}
					c++;
				} else if (i >= lvlNameStrt && i < lvlNameEnd) {
					tmpLvlName[i - lvlNameStrt] = (char) lvlData[i];
				} else if (i >= lvlHintStrt && i < lvlHintEnd) {
					tmpLvlHint[i - lvlHintStrt] = (char) lvlData[i];
				} else if (i >= lvlAuthorStrt && i < lvlAuthorEnd) {
					tmpLvlAuthor[i - lvlAuthorStrt] = (char) lvlData[i];
				} else if (i >= lvlDcltyStrt && i < lvlDcltyEnd) {
					tmpLvlDclty[i - lvlDcltyStrt] = lvlData[i];
				}
			}

			lvlName = new String(tmpLvlName);
			lvlAuthor = new String(tmpLvlAuthor);
			lvlHint = new String(tmpLvlHint);
			lvlDclty = Utils.getDifficulty(Integer.parseInt((tmpLvlDclty[0] + "" + tmpLvlDclty[1])));

		} catch (Exception e) {
			// TODO exception handling
		}

	}

	public void increaseLevel(){
		if (lvlNum <2030) lvlNum++;
		else lvlNum=1;
		this.loadLevel(lvlNum);
	}

	public void decreaseLevel(){
		if (lvlNum >1) lvlNum--;
		else lvlNum=1;
		this.loadLevel(lvlNum);
	}

	public PlayObjects[][] getLvlBaseField() {
		return lvlBaseField;
	}

	public void setLvlBaseField(PlayObjects[][] lvlBaseField) {
		this.lvlBaseField = lvlBaseField;
	}

	public PlayObjects[][] getLvlPlayField() {
		return lvlPlayField;
	}

	public void setLvlPlayField(PlayObjects[][] lvlPlayField) {
		this.lvlPlayField = lvlPlayField;
	}

	public String getLvlName() {
		return lvlName;
	}

	public void setLvlName(String lvlName) {
		this.lvlName = lvlName;
	}

	public String getLvlHint() {
		return lvlHint;
	}

	public void setLvlHint(String lvlHint) {
		this.lvlHint = lvlHint;
	}

	public String getLvlAuthor() {
		return lvlAuthor;
	}

	public void setLvlAuthor(String lvlAuthor) {
		this.lvlAuthor = lvlAuthor;
	}

	public Difficulty getLvlDclty() {
		return lvlDclty;
	}

	public void setLvlDclty(Difficulty lvlDclty) {
		this.lvlDclty = lvlDclty;
	}

	public Point getTankOrigPos() {
		return tankOrigPos;
	}

	public void setTankOrigPos(Point tankOrigPos) {
		this.tankOrigPos = tankOrigPos;
	}

	
}
